﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace TCP_Client
{
    public partial class Form1 : Form
    { 
        public Socket sockserver;
        public  Socket SockConnection;
        Thread Thread_ServerListen;
        Thread threadServer = null;
        Thread thread;
        Data_Crc data_Crc = new Data_Crc();//实例化CRC类
        Dictionary<string, Socket> DichScoket = new Dictionary<string, Socket>();//存放套接字
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();//
        Flag flag;
        TCP_ClientId ClientId;
        delegate void SetTextCallback(Button button,Color color);
        delegate void treeView_addCallback(string client_id);
   
        struct Flag
        {
            public bool upgrade;

        }
        struct TCP_ClientId
        {
            public int treeViewSelset;
            public string client_id;


        }
        Data data = new Data();
        public Form1()
        {
            InitializeComponent();
            flag = new Flag();
            ClientId =new TCP_ClientId();
            ClientId.client_id =null;
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

        }


        /// <summary>
        /// TCP发送函数
        /// </summary>
        /// <param name="mySigArray"></param>
        /// <param name="count"></param>
        public void Tcp_send(string client_id,byte[] mySigArray,Int32 count)
        {


            DichScoket[client_id].Send(mySigArray, count, SocketFlags.None);////发送数据   
        }
        //字符串转十六进制格式
        public string byteToHexStr(byte[] bytes, int buffer_length)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < buffer_length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }
        //服务器创建
        private void button3_Click(object sender, EventArgs e)
        {
           
            ClientId.client_id = null;
            if (button3.Text == "连接") { 
                string IIP = textBox1.Text;
              

               
                    IPAddress ip = IPAddress.Parse(IIP);//获取客户端的IP
                    IPEndPoint endPoint = new IPEndPoint(ip, int.Parse(textBox2.Text));
                    sockserver = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                    try
                    {
                        button3.Text = "断开";
                        sockserver.Bind(endPoint);
                        sockserver.Listen(100);
                         Thread_ServerListen = new Thread(ListenConnecting);
                        Thread_ServerListen.IsBackground = true;
                        Thread_ServerListen.Start();

                    }

                    catch
                    {

                    button3.Text = "连接";
                        return;
                    }

               

             

            }
            else if (button3.Text =="断开")
            {

                try
                {
                    
                    treeView1.Nodes.Clear();
                    foreach (string comn in DichScoket.Keys)
                    {
                        DichScoket[comn].Close();
                        DichScoket.Remove(comn);
                        dictThread[comn].Abort();
                        dictThread.Remove(comn);

                    }
                    sockserver.Close();
                    Thread_ServerListen.Abort();


                    button3.Text = "连接";
                }
                catch
                {

                    sockserver.Close();
                    treeView1.Nodes.Clear();
                    foreach (string comn in DichScoket.Keys)
                    {
                      
                        DichScoket[comn].Close();
                        DichScoket.Remove(comn);
                        dictThread[comn].Abort();
                        dictThread.Remove(comn);

                    }
                    button3.Text = "连接";
                    return;

                }
               
            }
        }
        //升级程序
        private void button1_Click(object sender, EventArgs e)
        {
            if (ClientId.client_id != null)
            {

                if (textBox3.Text == "")
                {
                    MessageBox.Show("选择bin文件");
                }
                else
                {

                    progressBar1.Value = 0;
                    thread = new Thread(send_pack);
                    thread.IsBackground = true;
                    thread.Start();
                }


            }
            else
            {

                MessageBox.Show("请选择升级设备");
                return;
            }
        }
        //擦除数据
        private void button2_Click(object sender, EventArgs e)
        {
         
     
            byte[] mySigArray = new byte[1400];
            UInt16 count = 0;

            mySigArray[count++] = 0x55;
            mySigArray[count++] = 0x33;
            mySigArray[count++] = 0x00;
            mySigArray[count++] = 0x00;
            mySigArray[count++] = 0x00;
            mySigArray[count++] = 0x00;

            mySigArray[count++] = 0x02;//擦除



            mySigArray[2] = (byte)((count - 1) >> 0 & 0xff);
            mySigArray[3] = (byte)((count - 1) >> 8 & 0xff);
            mySigArray[4] = (byte)((count - 1) >> 16 & 0xff);
            mySigArray[5] = (byte)((count - 1) >> 24 & 0xff);


            UInt16 crc16 = data_Crc.CRC_16(mySigArray, count);
            mySigArray[count++] = (byte)(crc16 >> 8);
            mySigArray[count++] = (byte)crc16;
            mySigArray[count++] = 0x55;
           Tcp_send(ClientId.client_id,mySigArray, count);////发送数据   
           Button_Show(button2, Color.Transparent);


        }
        //监听
        private void ListenConnecting()
        {

            while (true)  // 持续不断的监听客户端的连接请求；
            {

             
                try
                {
                     SockConnection = sockserver.Accept(); // 一旦监听到一个客户端的请求，就返回一个与该客户端通信的 套接字;
                     treeView1.Invoke(new treeView_addCallback(treeView_add), SockConnection.RemoteEndPoint.ToString());
                     DichScoket.Add(SockConnection.RemoteEndPoint.ToString(), SockConnection);
                     threadServer = new Thread(TCPserver_rev);
                     dictThread.Add(SockConnection.RemoteEndPoint.ToString(), threadServer);
                     threadServer.IsBackground = true;
                     threadServer.Start(SockConnection);
                 

                }
                catch
                {
                    return;
                }




            }
        }
        //TCP服务器接收数据
        private void TCPserver_rev(object aa )
        {

          
            Socket client_id = (Socket)aa;
            byte[] arrMsgRec = new byte[1024];
            int data_lenhgt;
            while (true)
            {
                if (client_id.Poll(-1,SelectMode .SelectRead))
                {
                    try
                    {
                        if (client_id.Connected)
                        {
                            data_lenhgt = client_id.Receive(arrMsgRec);
                         
                            if (data_lenhgt > 0)
                            {

                                if (data_Crc.check_data(arrMsgRec, (UInt16)data_lenhgt) == 0)
                                {


                                    if (arrMsgRec[6] == 0x01)
                                    {

                                        byte[] buffer = new byte[data_lenhgt-11];
                                        for (int i = 0; i < (data_lenhgt-11); i++)
                                        {
                                            buffer[i] = arrMsgRec[i + 8];

                                        }
                                      
                                        button5.Invoke(new SetTextCallback(Button_Show), button5, Color.Yellow);
                                        richTextBox3.Invoke(new treeView_addCallback(RichTextBox_show),"固件版本:"+ Encoding.ASCII.GetString(buffer));

                                    }
                                    else if (arrMsgRec[6] == 0x02)
                                    {

                                        button2.Invoke(new SetTextCallback(Button_Show), button2, Color.Yellow);
                                        richTextBox3.Invoke(new treeView_addCallback(RichTextBox_show), "擦除成功");

                                    }

                                    else if (arrMsgRec[6] == 0x03)
                                    {

                                        button1.Invoke(new SetTextCallback(Button_Show), button1, Color.Yellow);
                                        //   richTextBox3.Invoke(new treeView_addCallback(RichTextBox_show), "升级");
                                        flag.upgrade = true;

                                    }
                                    else if (arrMsgRec[6] == 0x04)
                                    {

                                        button6.Invoke(new SetTextCallback(Button_Show), button6, Color.Yellow);


                                    }
                                }



                            }


                        }

                    }
                    catch
                    {
                        return;

                        // DichScoket[client_id.ToString()].Close();//关闭连接
                        // DichScoket.Remove(client_id.ToString());
                        // treeView_delete(client_id.ToString());
                        // dictThread.Remove(client_id.ToString());

                    }
                }
                else
                {

                    MessageBox.Show(".......");
                 //   return;
                }
            }
           
        }
        //通讯测试
        private void button5_Click(object sender, EventArgs e)
        {



            if (ClientId.client_id != null)
            {

                byte[] mySigArray = new byte[1400];
                UInt16 count = 0;
                mySigArray[count++] = 0x55;
                mySigArray[count++] = 0x33;

                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x01;//通讯测试



                mySigArray[2] = (byte)((count - 1) >> 0 & 0xff);
                mySigArray[3] = (byte)((count - 1) >> 8 & 0xff);
                mySigArray[4] = (byte)((count - 1) >> 16 & 0xff);
                mySigArray[5] = (byte)((count - 1) >> 24 & 0xff);
                UInt16 crc16 = data_Crc.CRC_16(mySigArray, count);
                mySigArray[count++] = (byte)(crc16 >> 8);
                mySigArray[count++] = (byte)crc16;
                mySigArray[count++] = 0x55;
                try
                {

                    Tcp_send(ClientId.client_id,mySigArray,count);
              
                    Button_Show(button5, Color.Transparent);

                }
                catch
                {

                    Button_Show(button5, Color.Red);
                    return;
                }

            }

            else
            {

                MessageBox.Show("请选择升级设备");
                return;
            }

        }
        //打开文件
        private void button4_Click(object sender, EventArgs e)
        {

            byte[] mySigArray = new byte[1400];
            UInt32 file_len;
     
            OpenFileDialog openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
            openFileDialog1.Filter = "bin文件(*.bin)|*.bin";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox3.Text = openFileDialog1.FileName;//文件名称
                FileStream file_Read = new FileStream(textBox3.Text, FileMode.Open);
                label3.Text = "文件大小:" + file_Read.Length + "字节";
                file_len = (UInt32)file_Read.Length;//获取文件长度
                byte[] file_Byte = new byte[file_len];//开辟空间存放数据
                int r = file_Read.Read(file_Byte, 0, file_Byte.Length);//读取数据
                file_Read.Close();
              
              
             

            }
        }   
        //发送包
        public void send_data(byte[] data)
        {
            byte[] mySigArray = new byte[3000];
            UInt16 count = 0;
            int send_count =data.Length;
            int pack_count = 0;
            bool finsh=true;
            int value = 0;
            flag.upgrade = true;
            button1.Invoke(new SetTextCallback(Button_Show), button1, Color.Transparent);
        
            while (true)
            {
                try
                {

                    for(int i = 0; i < mySigArray.Length; i++)
                    {


                        mySigArray[i] = 0;
                    }

                    if (flag.upgrade == true)
                    {
                       
                        
                        mySigArray[count++] = 0x55;
                        mySigArray[count++] = 0x33;
                        mySigArray[count++] = 0x00;
                        mySigArray[count++] = 0x00;
                        mySigArray[count++] = 0x00;
                        mySigArray[count++] = 0x00;
                        mySigArray[count++] = 0x03;
                       

                        if (send_count > Convert.ToInt16(textBox4.Text))
                        {
                            for (Int16  i = 0; i < Convert.ToInt16(textBox4.Text); i++)
                            {
                               mySigArray[i + 7] = data[i + (pack_count * Convert.ToInt16(textBox4.Text))];
                               // mySigArray[i] = data[i + (pack_count * Convert.ToInt16(textBox4.Text))];
                                count++;
                            }

                        }

                        else if (send_count < Convert.ToInt16(textBox4.Text))
                        {
                            for (Int16 i = 0; i < send_count; i++)
                            {
                                 mySigArray[i + 7] = data[i+pack_count*1024];
                                // mySigArray[i] = data[i+pack_count*1024];
                                count++;
                            }
                            finsh = true;

                        }


                        
                        mySigArray[2] = (byte)((count - 1) >> 0 & 0xff);
                        mySigArray[3] = (byte)((count - 1) >> 8 & 0xff);
                        mySigArray[4] = (byte)((count - 1) >>16 & 0xff);
                        mySigArray[5] = (byte)((count - 1) >>24 & 0xff);
                        UInt16 crc16 = data_Crc.CRC_16(mySigArray, count);
                        mySigArray[count++] = (byte)(crc16 >> 8);
                        mySigArray[count++] = (byte)crc16;
                        mySigArray[count++] = 0x55;
                        
                        Tcp_send(ClientId.client_id,mySigArray, count);
                        flag.upgrade = false;
                        if (send_count >= Convert.ToInt16(textBox4.Text))
                        {
                            send_count = (send_count - Convert.ToInt16(textBox4.Text));
                            finsh = false;
                        }
                        value = value + ((count - 10));
                       progressBar1.Value = (int)value * 100 / data.Length;
                        count = 0;
                        pack_count++;
                        if (send_count < Convert.ToInt16(textBox4.Text) && finsh == true)
                        {

                            MessageBox.Show("升级完成。。。。。。。。");
                            break;
                        }

                    }

                 }
                catch
                {
                    button1.Invoke(new SetTextCallback(Button_Show), button1, Color.Red);
                    progressBar1.Value = 0;
                    MessageBox.Show("升级失败。。。。。。。。");
                    return;

                }




            }
        }

        public void send_pack()
        {

                FileStream fsRead = new FileStream(textBox3.Text, FileMode.Open);
                uint AllLen = (UInt32)fsRead.Length;
                UInt32 fsLen = AllLen;
                byte[] heByte = new byte[fsLen];
                int r = fsRead.Read(heByte, 0, heByte.Length);
                fsRead.Close();
                send_data(heByte);
                if (thread.IsAlive)
                    thread.Abort();


           
        }

        //窗体加载
        private void Form1_Load(object sender, EventArgs e)
        {


            textBox1.Text = GetIpAddress();
            ClientId.client_id = null;
            if (textBox3.Text!="")
            {

                FileStream fsRead = new FileStream(textBox3.Text, FileMode.Open);
                label3.Text = "文件大小:" + fsRead.Length + "字节";
                fsRead.Close();

            }
        }

        //获取主机名and主机IP地址
        public string GetIpAddress()
        {


            string strHostName = Dns.GetHostName(); //得到本机的主机名
            IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //取得本机IP
            string strAddr = ipEntry.AddressList[0].ToString(); //假设本地主机为单网卡

            return strAddr;

        }

        
        void Button_Show(Button button,Color color)
        {


            button.BackColor = color;




        }

        private void button6_Click(object sender, EventArgs e)
        {
           
                if (ClientId.client_id != null)
            {
                byte[] mySigArray = new byte[1400];
                UInt16 count = 0;

                mySigArray[count++] = 0x55;
                mySigArray[count++] = 0x33;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;

                mySigArray[count++] = 0x04;//重启



                mySigArray[2] = (byte)((count - 1) >> 0 & 0xff);
                mySigArray[3] = (byte)((count - 1) >> 8 & 0xff);
                mySigArray[4] = (byte)((count - 1) >> 16 & 0xff);
                mySigArray[5] = (byte)((count - 1) >> 24 & 0xff);


                UInt16 crc16 = data_Crc.CRC_16(mySigArray, count);
                mySigArray[count++] = (byte)(crc16 >> 8);
                mySigArray[count++] = (byte)crc16;
                mySigArray[count++] = 0x55;
                try
                {

                    Tcp_send(ClientId.client_id, mySigArray, count);////发送数据   
                    Button_Show(button6, Color.Transparent);

                }
                catch
                {
                    Button_Show(button6, Color.Red);
                    return;
                }
            }
                else
            {

                MessageBox.Show("请选择升级设备");
                return;
            }

        }
        private void linkLabel4_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.openmcu.com/");
        }

        private void linkLabel2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            System.Diagnostics.Process.Start("https://openmcu.taobao.com/");
        }

        private void linkLabel1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.openmcu.com/forum.php");
        }

        private void Form1_SizeChager(object sender, EventArgs e)
        {

            if (this.WindowState == FormWindowState.Minimized) //判断是否最小化
            {
                this.ShowInTaskbar = false; //不显示在系统任务栏
                notifyIcon1.Visible = true; //托盘图标可见
            }
        }
        //关闭窗体，释放资源
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dr = MessageBox.Show("是否退出?", "提示:", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);

            if (dr == DialogResult.OK)   //如果单击“是”按钮
            {

                System.Environment.Exit(System.Environment.ExitCode);
                this.Dispose();
                e.Cancel = false;


            }
            else if (dr == DialogResult.Cancel)
            {
                e.Cancel = true;                  //不执行操作
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {

            if (this.WindowState == FormWindowState.Minimized)
            {
                this.ShowInTaskbar = true; //显示在系统任务栏
                this.WindowState = FormWindowState.Normal; //还原窗体
                notifyIcon1.Visible = false; //托盘图标隐藏
            }
        }

        private void button2_Click_1(object sender, EventArgs e)
        {

            if (ClientId.client_id != null)
            {
                byte[] mySigArray = new byte[1400];
                UInt16 count = 0;

                mySigArray[count++] = 0x55;
                mySigArray[count++] = 0x33;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;
                mySigArray[count++] = 0x00;

                mySigArray[count++] = 0x02;//擦除



                mySigArray[2] = (byte)((count - 1) >> 0 & 0xff);
                mySigArray[3] = (byte)((count - 1) >> 8 & 0xff);
                mySigArray[4] = (byte)((count - 1) >> 16 & 0xff);
                mySigArray[5] = (byte)((count - 1) >> 24 & 0xff);


                UInt16 crc16 = data_Crc.CRC_16(mySigArray, count);
                mySigArray[count++] = (byte)(crc16 >> 8);
                mySigArray[count++] = (byte)crc16;
                mySigArray[count++] = 0x55;
                try
                {

                    Tcp_send(ClientId.client_id, mySigArray, count);////发送数据   
                    Button_Show(button2, Color.Transparent);

                }
                catch
                {
                    Button_Show(button2, Color.Red);
                    return;
                }
            }

            else
            {

                MessageBox.Show("请选择升级设备");
                return;
            }
        }
        public void treeView_add(string client_id)
        {


            TreeNode node1 = new TreeNode();
            node1.Tag = 1;
            node1.Text = client_id;
            treeView1.Nodes.Add(node1);



        }
        public void treeView_delete(string client_id)
        {
           

            foreach (TreeNode node in treeView1.Nodes)
            {
                if (node.Text == client_id)
                {

                    node.Remove();
                    

                }
            }


        }
           
        public void  RichTextBox_show(string str)
        {

            richTextBox3.AppendText(str);
            richTextBox3.AppendText(Environment.NewLine);

        } 

        private void treeView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {

            ClientId.client_id= treeView1.SelectedNode.Text.ToString();
        }
    }
}
